/*
 * Copyright (c) 2011 Ball State University
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * NOTE:
 * Derivative work based on the Google IO 2011 Schedule app released for open source
 * http://code.google.com/p/iosched/
 */

package edu.bsu.android.gtv.apps.bconnected.ui; 

import java.util.ArrayList;

import com.google.android.imageloader.ImageLoader;

import edu.bsu.android.gtv.apps.bconnected.objects.SISession;
import edu.bsu.android.gtv.apps.bconnected.data.SISessionData;
import edu.bsu.android.gtv.apps.bconnected.objects.Tutor;
import edu.bsu.android.gtv.apps.bconnected.data.TutorData;
import edu.bsu.android.gtv.apps.bconnected.data.ConnectionData;
import edu.bsu.android.gtv.apps.bconnected.R;
import edu.bsu.android.gtv.apps.bconnected.objects.Person;
import edu.bsu.android.gtv.apps.bconnected.ui.base.BaseActivity;
import edu.bsu.android.gtv.apps.bconnected.util.Adapters;
import edu.bsu.android.gtv.apps.bconnected.util.AnalyticsUtils;
import edu.bsu.android.gtv.apps.bconnected.util.Constants;
import edu.bsu.android.gtv.apps.bconnected.util.FractionalTouchDelegate;
import edu.bsu.android.gtv.apps.bconnected.util.LoginHelper;
import edu.bsu.android.gtv.apps.bconnected.util.UIUtils;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.RectF;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.LinearLayout;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;

/**
 * An activity that shows the course tutor information. Activity that is started when a user selects an 
 * tutor from the list on the {@link CourseInfoActivity}.
 * @author Kyle Parker, University Computing Services
 */
public class TutorInfoActivity extends BaseActivity {   
    private static final String TAG = "TutorInfoActivity";
    private static final String TAG_SI_SESSION = "si"; 
    private static final String TAG_LEARNING_CENTER = "lc"; 
    
    private TabHost mTabHost;
    private View mLoadingSpinner;
    private View mSISessionSpinner;
    private Activity mActivity;
    private BroadcastReceiver mReceiver;
    private CompoundButton mStarred;
    private Tutor mTutor;

    private String mBSUID;
    private String mLoginGuid;
    private String mDiscCode;
    private String mCourseNum;
    private String mSection;
    private String mTermID;
    private String mBuildingDesc;
    private String mLatitude;
    private String mLongitude;
    private boolean mLogin;

    private int mTutorPosition = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_tutor_info);
		
        getActivityHelper().setupActionBar(false, "Course Schedule | Tutor");        
        mActivity = this;
        
        handleLogout();    
        handleLogin();
                
        mTabHost = (TabHost) findViewById(android.R.id.tabhost);
       	mTabHost.setup();

        mLoadingSpinner = findViewById(R.id.loading_spinner); 
        mLoadingSpinner.setVisibility(View.VISIBLE); 
        
        mSISessionSpinner = findViewById(R.id.spinner_si_sessions); 
        mSISessionSpinner.setVisibility(View.VISIBLE);  
        
        mStarred = (CompoundButton) findViewById(R.id.star_button);
        mStarred.setFocusable(true);
        mStarred.setClickable(true);
        
        // Larger target triggers star toggle
        final View starParent = findViewById(R.id.name);
        FractionalTouchDelegate.setupDelegate(starParent, mStarred, new RectF(0.6f, 0f, 1f, 0.8f));

        setupSISessionTab(); 
        setupLearningCenterTab(); 
        
        getExtras();

		// Hide the tutor while the data is loading
        hideTutorInfo();
		if (mLogin) {
			loadTutorInfo();
		}

        AnalyticsUtils.getInstance(mActivity).trackPageView("/Tutor");
    }
    
    @Override 
    public void onDestroy() {
    	super.onResume();
    	mActivity.unregisterReceiver(mReceiver);
    }
    
    /**
     * Get the extras from the Intent
     */
    public void getExtras() {
		Bundle extras = getIntent().getExtras(); 

		if (extras != null) {
			if (extras.getString(Constants.EXTRA_TUTOR_POSITION) != null) {
				mTutorPosition = Integer.parseInt(extras.getString(Constants.EXTRA_TUTOR_POSITION));
			}
			if (extras.getString(Constants.EXTRA_DISC_CODE) != null) {
				mDiscCode = extras.getString(Constants.EXTRA_DISC_CODE);
			}
			if (extras.getString(Constants.EXTRA_COURSE_NUM) != null) {
				mCourseNum = extras.getString(Constants.EXTRA_COURSE_NUM);
			}
			if (extras.getString(Constants.EXTRA_SECTION) != null) {
				mSection = extras.getString(Constants.EXTRA_SECTION);
			}
			if (extras.getString(Constants.EXTRA_TERM_ID) != null) {
				mTermID = extras.getString(Constants.EXTRA_TERM_ID);
			}
		}
    }

    /**
     * Using a new thread, separate from the main activity, load the tutor information from the service handler
     */
    private void loadTutorInfo() {
        Runnable load = new Runnable(){
            public void run() {
            	try {
	            	if (TutorData.getTutorCount() > 0) {
	                	mTutor = TutorData.getTutor(mTutorPosition);

	            		if (mTutor.getImageURL() != null) {
		                    ImageLoader imageLoader = new ImageLoader();
		                    
		                    ImageView image = (ImageView) findViewById(R.id.building_photo);
		                    image.setVisibility(View.VISIBLE);
		                    image.setTag(mTutor.getImageURL().toString());
		                    image.setContentDescription(mTutor.getBuildingDesc());
		                    String url = mTutor.getImageURL().toString();
		                    imageLoader.bind(image, url, null);
	            		}
	            	}
	    	    	
	        		mActivity.runOnUiThread(returnTutor);
            	} catch (Exception ex) {
                    AnalyticsUtils.getInstance(mActivity).trackPageView(TAG + ": " + ex.getMessage());
            	}
            }
        };
        
        Thread thread = new Thread(null, load, "loadTutor");
        thread.start();
    }
    
    /**
     * Load the tutor info from the service handler and set the visibility of the spinner to "gone"
     */
    private Runnable returnTutor = new Runnable(){
        public void run() {
        	displayTutor();
            mLoadingSpinner.setVisibility(View.GONE);
        }
    };

    /**
     * Using a new thread, separate from the main activity, load the session schedule from the service handler
     */
    private void loadSISession() {			
        Runnable load = new Runnable(){
            public void run() { 
            	try {
            		SISessionData.initializeSISession(mActivity, mDiscCode, mCourseNum, mSection, mTermID);
        	    	
            		mActivity.runOnUiThread(returnSISession);   
            	} catch (Exception ex) {
                    AnalyticsUtils.getInstance(mActivity).trackPageView(TAG + ": " + ex.getMessage());
            	}
            }
        };
        
        Thread thread = new Thread(null, load, "loadOtherCourse");
        thread.start();
    }

    /**
     * Display the session schedule in a separate thread
     */
    private Runnable returnSISession = new Runnable(){
        public void run() {
            displaySISessions(SISessionData.getSISessions());
            mSISessionSpinner.setVisibility(View.GONE);
            
            if (SISessionData.getSISessionCount() == 0) {
                TextView empty = ((TextView) findViewById(R.id.empty_si_sessions));
                empty.setVisibility(View.VISIBLE);
            }
        }
    };
    
    /**
     * Display the tutor information, set the starred status and show the other courses taught
     */
    private void displayTutor() {
        if (mTutor != null) { 
        	LinearLayout view = (LinearLayout) findViewById(R.id.tutor_info_container);
            view.setVisibility(View.VISIBLE);
        	view.setBackgroundResource(R.color.content_background);
            
            loadSISession();

    		mBuildingDesc = mTutor.getBuildingDesc();
    		mLongitude = mTutor.getLongitude();
    		mLatitude = mTutor.getLatitude();
    		
    		String name = (mTutor.getNamePrefix() + " " + mTutor.getFirstName() + " " + mTutor.getLastName() + " " + 
    				mTutor.getNameSuffix()).trim();
    		
    		UIUtils.displayTextView(view, R.id.name, name);
    		UIUtils.displayTextView(view, R.id.email, mTutor.getEmailAddress());
    		UIUtils.displayTextView(view, R.id.phone, mTutor.getPhone());
    		UIUtils.displayTextView(view, R.id.title, mTutor.getTitleRank());
    		UIUtils.displayTextView(view, R.id.department, mTutor.getDepartment());
    		UIUtils.displayTextView(view, R.id.office, mTutor.getBuildingCode() + " " + mTutor.getRoom());

    		UIUtils.displayTextView(view, R.id.headline, mTutor.getHeadline());
    		UIUtils.displayTextView(view, R.id.services, mTutor.getTagline());
	        
            // Unregister around setting checked state to avoid triggering listener since change isn't user generated.
            mStarred.setOnCheckedChangeListener(null);
            mStarred.setChecked(mTutor.getStarred());
            mStarred.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
			    	ConnectionData.insertConnection(mBSUID, mLoginGuid, mTutor.getBSUID(), Integer.parseInt(mTutor.getPersonType()), 
			    			isChecked, mActivity);
			    }           	
            });
    	} else {  
    		hideTutorInfo();
    		((TextView) showEmptyTutorInfo().findViewById(R.id.empty_tutor_info)).setText(R.string.empty_tutor_info);
    	}
    }

    /** 
     * Hide the tutor view during the load process or if the tutor object is empty
     */
	private void hideTutorInfo() { 
		LinearLayout view = (LinearLayout) findViewById(R.id.tutor_info_container);
        view.setVisibility(View.GONE);			
	}

    /**
     * Show the tutor view during the load process or if the tutor object is empty
     */
	private View showEmptyTutorInfo() {
		LinearLayout view = (LinearLayout) findViewById(R.id.empty_tutor_info_container);
		view.setVisibility(View.VISIBLE);
        view.setBackgroundResource(R.drawable.empty_schedule);
        
        return view;
	}

	/**
     * Display the schedule for the supplemental instruction courses
     */
    private void displaySISessions(ArrayList<SISession> siSessions) { 		
    	Adapters.SISessionAdapter adapter = new Adapters.SISessionAdapter(mActivity, siSessions);

        final ListView lv = ((ListView) findViewById(R.id.si_sessions));
        lv.setAdapter(adapter);
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = new MenuInflater(this);
    	inflater.inflate(R.menu.map_menu_items, menu);
    	
    	super.onCreateOptionsMenu(menu);
        
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_map:
            	Intent intent = UIUtils.getGoogleMapsIntent(mBuildingDesc, mLatitude, mLongitude);
            	
            	if (intent != null) {
            		startActivity(intent);
            	} else {
                    final String errorText = mActivity.getString(R.string.toast_error_location); 
                    Toast.makeText(mActivity, errorText, Toast.LENGTH_LONG).show();
            	}
                return true;
        }
        
        return super.onOptionsItemSelected(item);
    }

    /**
     * Build and add "supplemental instruction session" tab.
     */
    private void setupSISessionTab() {
        mTabHost.addTab(mTabHost.newTabSpec(TAG_SI_SESSION)
                .setIndicator(UIUtils.buildIndicator(R.string.tab_si_session, mActivity))
                .setContent(R.id.tab_si_session)); 
    }

    /**
     * Build and add "learning center" tab.
     */
    private void setupLearningCenterTab() {
        mTabHost.addTab(mTabHost.newTabSpec(TAG_LEARNING_CENTER)
                .setIndicator(UIUtils.buildIndicator(R.string.tab_learning_center, mActivity))
                .setContent(R.id.tab_learning_center)); 
    }

    /**
     * In order to protect the activity from the back stack after a student logs out, remove the activity 
     * If the student hits the back button, this will take them to the Home activity
     */
    private void handleLogout() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Constants.ACTION_LOGOUT);
        mReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
			    Log.d("onReceive","Logout in progress");
		        intent = new Intent(Intent.ACTION_VIEW, null, mActivity, HomeActivity.class);
		        intent.putExtra(Constants.EXTRA_LOGIN_STATUS, Integer.toString(Constants.LOGIN_STATUS_LOGOUT));
		        
		        mActivity.startActivity(intent); 
			    mActivity.finish();
			}
		};
		
        mActivity.registerReceiver(mReceiver, intentFilter);
    }
    
    /**
     * Determine if the person has logged in and whether there is a person object in the database
     * Get the student's BSU ID for use throughout the application
     */
    private void handleLogin() {
    	Person person = LoginHelper.checkLogin(mActivity);
    	
    	if (person != null) {
    		mBSUID = person.getBSUID();
        	mLoginGuid = person.getLoginGuid();
        	mLogin = true;
    	} else {
	        Intent intent = new Intent(Intent.ACTION_VIEW, null, mActivity, HomeActivity.class);
	        intent.putExtra(Constants.EXTRA_LOGIN_STATUS, Integer.toString(Constants.LOGIN_STATUS_NOT_LOGGED_IN));
	        
	        mActivity.startActivity(intent); 
		    mActivity.finish();
		    
		    mLogin = false;
    	}    	
    }
}
